package org.dreamwork.jasmine2.web.controls;

import org.dreamwork.jasmine2.configure.JasmineConfig;
import org.dreamwork.jasmine2.engine.HttpContext;
import org.dreamwork.jasmine2.engine.IPostbackHandler;
import org.dreamwork.jasmine2.engine.IClickable;
import org.dreamwork.jasmine2.events.ClickableDelegate;
import org.dreamwork.jasmine2.events.IClickListener;
import org.dreamwork.jasmine2.events.EventException;
import org.dreamwork.jasmine2.i18n.I18nUtil;
import org.dreamwork.jasmine2.web.IWebControl;
import org.dreamwork.jasmine2.util.DataBinder;
import org.dreamwork.jasmine2.util.StringConverter;
import org.dreamwork.util.NameValueCollection;
import org.dreamwork.util.StringUtil;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: seth
 * Date: 2009-7-24
 * Time: 11:39:05
 */
public class CheckBox extends WebControl implements IPostbackHandler, IClickable {
    private String text;
    private String value;
    private String textField;
    private boolean checked = false;

    protected String type = "checkbox";

    private ClickableDelegate delegate = new ClickableDelegate ();

    public void init () {
        super.init ();
        htmlTagName = "input";

        if (runAtServer && autoPostback) {
            page.registerClientScriptBlock (InternalJS.class, InternalJS.ON_CLICK_JS);
            attrs.setProperty ("onchange", "__client_stub (this, 'click', null)");
        }
    }

    public String getText () {
        return text;
    }

    public void setText (String text) {
        this.text = text;
    }

    public String getValue () {
        return value;
    }

    public void setValue (String value) {
        this.value = value;
    }

    public boolean isChecked () {
        return checked;
    }

    public void setChecked (boolean checked) {
        this.checked = checked;
    }

    public String getTextField () {
        return textField;
    }

    public void setTextField (String textField) {
        this.textField = textField;
    }

    public void setAttribute (String attrName, String attrValue) {
        if ("text".equalsIgnoreCase (attrName))
            text = attrValue;
        else if ("value".equalsIgnoreCase (attrName))
            value = attrValue;
        else
            super.setAttribute (attrName, attrValue);
    }

    // events
    public void addClickListener (IClickListener listener) {
        delegate.addClickListener (listener);
    }

    public void removeClickListener (IClickListener listener) {
        delegate.removeClickListener (listener);
    }

    public void fireControlClicked (IWebControl sender) throws EventException {
        delegate.fireControlClicked (sender);
    }

    public IClickListener[] getClickListeners () {
        return delegate.getClickListeners ();
    }

    // override
    public void postbackData (NameValueCollection props) {
        if (page.isPostback ()) {
            String value = props.getValue (getName ());
            checked = value != null && value.equals (this.value);
        }
    }

    protected void loadViewState (Object savedState) throws IOException {
        super.loadViewState (savedState);
        Object value = stateManager.get ("value");
        if (value != null)
            this.value = value.toString ();
        Object text = stateManager.get ("text");
        if (text != null)
            this.text = text.toString ();
    }

    public void onDataBind (Object sender) throws EventException {
        super.onDataBind (sender);
        if (dataSource != null && valueField != null) {
            Object value = DataBinder.getValue (dataSource, valueField);
            checked = StringConverter.equals (value, this.value);
            if (!checked) {
                this.value = StringConverter.contvertToString (value);
                if (attrs.containsKey ("checked")) attrs.remove ("checked");
            }

            if (textField != null) {
                value = DataBinder.getValue (dataSource, textField);
                if (value != null)
                    setText (value.toString ());
            }

            stateManager.put ("value", this.value);
            stateManager.put ("text", this.text);
        }
    }

    @Override
    public void onPrerender (IWebControl sender, HttpContext context) throws EventException {
        super.onPrerender (sender, context);

        if (!StringUtil.isEmpty (text)) {
            if (context.getApplication ().getAttribute (JasmineConfig.JASMINE_I18N_HOLDER) != null)
                text = I18nUtil.eval (text, this);
            text = I18nUtil.escapeI18n (text);
        }
    }

    public void render (PrintWriter writer) throws IOException, EventException {
        if (attrs.containsKey ("type")) attrs.remove ("type");
        if (attrs.containsKey ("checked")) {
            String s = attrs.getProperty ("checked");
            if ("false".equalsIgnoreCase (s))
                attrs.remove ("checked");
        }
        String clientId = getClientId ();
        String componentName = name == null ? clientId : name;

        if (!StringConverter.isEmpty (value))
            attrs.setProperty ("value", value);

        writer.write ("<input type=\"" + type + "\" name=\"" + componentName + "\"");
        attrs.setProperty ("id", clientId);
        if (!editable) writer.write (" disabled");
        super.renderAttributes (writer);
        if (checked) writer.write (" checked");
        writer.write ("/>");

        if (!StringConverter.isEmpty (text)) {
            writer.write (" <label for=\"" + clientId + "\">");
            writer.write (text);
            writer.println ("</label>");
        }
    }

    Properties getAttributes () {
        return attrs;
    }

    Map<String, String> getStyles () {
        return style;
    }

    Map getOldAttributes () {
        return this.oldAttributes;
    }

    Map getDynamicAttributes () {
        return this.dynamicAttributes;
    }
}